import Singleton from "../common/Singleton";
import { Logger } from "../log/logger";
import Utils from "../utils/Utils";
import { Fview, GObjectPool, UIPackage } from "./UIDefine";

interface ILoadInfo {
    urlList: string[];
    loadTask: Promise<void>;
}

/**ui包管理 */
export default class UIRes extends Singleton {

    static get I(): UIRes {
        return this.Instance();
    }

    /**引用列表 */
    private refInfo: Map<string, number> = new Map<string, number>();

    /**UI对象池 */
    private poolDir = new GObjectPool();

    /**预加载列表 */
    // private proLoadList: ILoadInfo[] = [];

    /**待销毁列表 */
    private removeList: Set<string> = new Set<string>();

    hasPkg(names: string[]) {
        for (let elm of names) {
            let v = this.refInfo.get(elm);
            if (Utils.isNil(v) || v <= 0) {
                return false;
            }
        }
        return true;
    }


    loadByPromise(pkg: string | string[]) {
        return new Promise((resolve, reject) => {
            this.loadPackage(pkg, Laya.Handler.create(this, ret => {
                if (ret) {
                    resolve(ret);
                } else {
                    reject("load package error:" + pkg);

                }
            }));
        })
    }

    loadPackage(pkgName: string | string[], complete: Laya.Handler, progress?: Laya.Handler) {
        let pkgs = typeof (pkgName) === "string" ? [pkgName] : pkgName;
        for (let elm of pkgs) {
            this.addRefrence(elm);
        }
        
        UIPackage.loadPackage(pkgName, complete, progress)
    }

    getObject<T extends Fview>(v: new () => T) {
        let url = v["URL"];
        if (!url || !UIPackage.normalizeURL(url)) {
            Logger.logView(v, "获取不存在的UI")
            return;
        }
        return <T>this.poolDir.getObject(url);
    }

    /**回收 */
    recoverObject<T extends Fview>(instance: T) {
        this.poolDir.returnObject(instance);
    }

    /**销毁 */
    disposView<T extends Fview>(pkgName: string, view: T) {
        this.removeRefrence(pkgName);
        view.dispose();
    }


    addRefrence(pkgName: string) {
        let v = this.refInfo.get(pkgName);
        v = Utils.isNil(v) ? 1 : ++v;
        this.refInfo.set(pkgName, v);
    }

    removeRefrence(pkgName: string) {
        let v = this.refInfo.get(pkgName);
        if (Utils.isNil(v) || v <= 0) {

            return;
        }

        --v;
        if (v <= 0) {
            this.removeList.add(pkgName);
            this.refInfo.delete(pkgName);
        }
    }

    /**清理资源，只会清理未引用的 */
    clear() {
        let array = this.removeList;
        if (array.size <= 0) {
            return array;
        }

        array.forEach(v => {
            let refV = this.refInfo.get(v);
            if (!refV || refV <= 0) {
                Logger.logView(v, "清理UI资源")
                UIPackage.removePackage(v);
            }
        })

        array.clear();
    }

}